package com.raymond.util;

import com.raymond.entity.commons.PageRequest;
import com.raymond.entity.commons.PageResponse;
import com.raymond.entity.commons.SummaryResponse;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * desc-分页辅助工具类
 *
 * @author houmenghe
 * @date 2025/04/21 17:32
 **/
public class PageUtil {

    private PageUtil() {
    }

    /**
     * 分页数据组装公共方法
     *
     * @param searchEntity     查询实体
     * @param listAction       列表查询方法
     * @param totalCountAction 总记录查询方法
     * @param <T>              数据明细类型
     * @return 分页组装数据
     */
    public static <T> PageResponse<T> process(PageRequest searchEntity,
                                              Supplier<List<T>> listAction,
                                              Supplier<Integer> totalCountAction) {
        List<T> rows = listAction.get();
        Integer totalCount = 0;

        if (searchEntity.isQueryTotal() && CollectionUtils.isNotEmpty(rows)) {
            totalCount = totalCountAction.get();
        }

        PageResponse<T> pageResponse = PageResponse.create(rows, searchEntity);

        pageResponse.setTotal(totalCount);

        return pageResponse;
    }

    /**
     * 分页数据组装公共方法
     *
     * @param searchEntity       查询实体
     * @param listAction         列表查询方法
     * @param totalCountAction   总记录查询方法
     * @param summaryCountAction 汇总查询方法
     * @param <T>                数据明细类型
     * @return 分页组装数据
     */
    public static <T> SummaryResponse<T> process(PageRequest searchEntity,
                                                 Supplier<List<T>> listAction,
                                                 Supplier<Integer> totalCountAction,
                                                 Supplier<Map<String, Long>> summaryCountAction) {
        List<T> rows = listAction.get();
        Integer totalCount = 0;

        if (searchEntity.isQueryTotal() && CollectionUtils.isNotEmpty(rows)) {
            totalCount = totalCountAction.get();
        }

        PageResponse<T> pageResponse = PageResponse.create(rows, searchEntity);

        pageResponse.setTotal(totalCount);

        SummaryResponse<T> summaryResponse = new SummaryResponse<>();
        summaryResponse.setPageNo(pageResponse.getPageNo());
        summaryResponse.setPageSize(pageResponse.getPageSize());
        summaryResponse.setDatas(pageResponse.getDatas());
        summaryResponse.setTotal(pageResponse.getTotal());
        summaryResponse.setSummary(summaryCountAction.get());

        return summaryResponse;
    }


    /**
     * 分页查询
     *
     * @param datas    全部参数列表
     * @param function 根据分页参数查询数据
     * @param <T>      输入参数类型
     * @param <R>      返回列表类型
     * @return 分类数据
     */
    public static <T, R> List<R> getListForPage(List<T> datas, Function<List<T>, List<R>> function) {
        return getListForPage(datas, 100, function);
    }


    /**
     * 分页查询
     *
     * @param datas    全部参数列表
     * @param rows     每页多少条
     * @param function 根据分页参数查询数据
     * @param <T>      输入参数类型
     * @param <R>      返回列表类型
     * @return 分类数据
     */
    public static <T, R> List<R> getListForPage(List<T> datas, int rows, Function<List<T>, List<R>> function) {
        List<R> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(datas)) {
            Integer startIndex = 0;
            Integer endIndex = rows;
            //分页查询
            int size = datas.size();
            List<T> subSysNoList = null;
            while (true) {
                if (endIndex <= size) {
                    subSysNoList = datas.subList(startIndex, endIndex);
                } else if (startIndex < size) {
                    subSysNoList = datas.subList(startIndex, size);
                } else {
                    break;
                }
                List<R> apply = function.apply(subSysNoList);
                if (CollectionUtils.isNotEmpty(apply)) {
                    list.addAll(apply);
                }
                startIndex += rows;
                endIndex += rows;
            }
        }
        return list;
    }

}
